package com.windaka.elements.utils;

import org.springframework.cglib.beans.BeanCopier;

import java.util.ArrayList;
import java.util.List;


/**
 * <p><strong>CglibBeanCopier拷贝类</strong></p>
 * <p>
 *     速度比BeanUtils快的多 <br>
 *     对象拷贝 常用与 DO DTO PO VO之间的相互拷贝 <br>
 *     相同字段名之间 将值进行拷贝 <br>
 * </p>
 * <li>
 * <p>
 *     <strong>示例1: 对象之间进行拷贝</strong> <br>
 *     CglibBeanCopierUtils.copy(school, schoolVO);
 * </p>
 * </li>
 * <li>
 * <p>
 *     <strong>示例2: 传入List拷贝后返回List</strong> <br>
 *     List resultList = CglibBeanCopierUtils.copy(dataList, new School(), new SchoolVO());
 * </p>
 * </li>
 * @author song
 *
 * @see BeanCopier
 * @see Object
 * @see List
 * @since 10:02 2021/7/31
 **/
public class CglibBeanCopierUtils {

    private CglibBeanCopierUtils() {}
    
    /**
     * <p>
     *     <strong>示例1: 对象之间进行拷贝</strong> <br>
     *     CglibBeanCopierUtils.copy(school, schoolVO);
     * </p>
     * @param source 原对象
     * @param target 拷贝对象
     * @author song
     * @since 9:10 2021/8/5
    **/
    public static void copy(Object source, Object target) {
        BeanCopier copier = BeanCopier.create(source.getClass(), target.getClass(), false);
        copier.copy(source, target, null);
    }
    
    /**
     * <p>
     *     <strong>示例2: 传入List拷贝后返回List</strong> <br>
     *     List resultList = CglibBeanCopierUtils.copy(dataList, new School(), new SchoolVO());
     * </p>
     * @param sourceList 原对象组
     * @param source 原对象
     * @param target 目标对象
     * @author song
     * @since 11:49 2021/8/18
    **/
    public static List<?> copy(List<?> sourceList, Object source, Object target) {
        List<Object> targetList = new ArrayList<>();
        BeanCopier copier = BeanCopier.create(source.getClass(), target.getClass(), false);
        for (Object sourceObject : sourceList) {
            Class<?> clz = target.getClass();
            Object targetObject;
            try {
                targetObject = clz.newInstance();
                copier.copy(sourceObject, targetObject, null);
            } catch (Exception e) {
                e.printStackTrace();
                return sourceList;
            }
            targetList.add(targetObject);
        }
        return targetList;
    }

}
